<template>
  <el-table
    ref="tableRef"
    v-loading="loading"
    height="100%"
    class="overflow-y-auto basic-table"
    :tooltip-options="{ popperClass: 'basic-tooltip' }"
    :data="data"
    row-key="id"
    :row-class-name="tableRowClassName"
    @row-click="handleTableRowClick"
    @selection-change="handleTableSelectionChange"
    @sort-change="handleSortChange"
  >
    <!--
      @select="handleTableSelectionChange"
      @select-all="handleTableSelectionChange"
    v-el-table-infinite-scroll="() => emit('load-more')"
   :infinite-scroll-immediate="false"
    :infinite-scroll-distance="50"
    :infinite-scroll-disabled="disabled"
    <template #append>
      <section
        v-if="data.length"
        class="flex items-center justify-center w-full h-10 text-[#BFC2C7]"
      >
        <span v-if="data.length === pagination.total">没有更多内容了</span>
        <span v-else>加载中...</span>
      </section>
    </template>
  -->
    <template #empty><table-empty /></template>
    <el-table-column type="selection" width="40" />
    <el-table-column
      prop="primary_domain"
      label="域名"
      :formatter="emptyFormatter"
      min-width="116"
      show-overflow-tooltip
    />
    <el-table-column
      prop="domain_list"
      label="其他域名"
      show-overflow-tooltip
      :formatter="emptyFormatter"
      min-width="116"
    >
      <template #default="{ row }">
        {{ (row?.domain_list ?? []).join(',') || '' }}
      </template>
    </el-table-column>
    <el-table-column prop="provider" label="申请方式" min-width="82">
      <template #default="{ row }">
        {{ getOptionsLabel(applyMethodOptions, row.provider) || '-' }}
      </template>
    </el-table-column>
    <el-table-column
      prop="acme_account"
      label="Acme账号"
      show-overflow-tooltip
      :formatter="emptyFormatter"
      min-width="116"
    >
      <template #default="{ row }">
        {{ emptyText(row.acme_account?.email) }}
      </template>
    </el-table-column>
    <el-table-column
      prop="status"
      label="状态"
      :formatter="emptyFormatter"
      min-width="80"
    >
      <template #default="{ row }">
        <span :style="{ color: CERT_COLOR_MAP[row.status] }">
          {{ getOptionsLabel(certStatusOptions, row.status) || '-' }}
        </span>
      </template>
    </el-table-column>
    <el-table-column prop="rr_num" label="日志" min-width="60">
      <template #default="{ row }">
        <app-icon
          name="log"
          size="16px"
          color="#BFC2C7"
          class="hover:text-[#1D2129]"
          @click.stop="handleLog(row)"
        />
      </template>
    </el-table-column>
    <el-table-column
      prop="organization"
      label="颁发组织"
      show-overflow-tooltip
      :formatter="emptyFormatter"
      min-width="116"
    />
    <el-table-column
      prop="auto_renew"
      label="自动续签"
      :formatter="emptyFormatter"
      min-width="80"
    >
      <template #default="{ row }">
        <el-switch
          v-model="row.auto_renew"
          :loading="row.loading"
          :disabled="row.provider === APPLY_METHOD.HAND_ANALYSIS"
          :before-change="() => handleChangeStatus(row)"
          @click.stop
        />
      </template>
    </el-table-column>
    <el-table-column
      prop="expire_date"
      label="到期时间"
      :formatter="emptyFormatterUnix"
      min-width="160"
    >
      <!-- sortable="custom" -->
      <template #default="{ row }">
        <span :class="getTimeIsExpires(row.expire_date) ? 'text-[#F53F3F]' : ''"
          >{{ formatUnix(row.expire_date) }}
        </span>
      </template>
    </el-table-column>
    <el-table-column min-width="160" prop="description" label="备注">
      <template #default="{ row }">
        <basic-edit-table-remark
          :content="row.description"
          :submit="value => handleEditRemark(row.id, value)"
        />
      </template>
    </el-table-column>
    <el-table-column label="操作" prop="action" fixed="right" width="220">
      <template #default="{ row }">
        <div class="flex justify-between">
          <el-button
            :class="
              row.status === CERT_STATUS.NORMAL
                ? 'text-[#BEDAFF]'
                : 'text-primary'
            "
            link
            :disabled="row.status === CERT_STATUS.NORMAL"
            @click.stop="handleDetail(row)"
          >
            详情
          </el-button>
          <el-button
            :class="
              row.status === CERT_STATUS.APPLYING
                ? 'text-[#BEDAFF]'
                : 'text-primary'
            "
            link
            :disabled="row.status === CERT_STATUS.APPLYING"
            @click.stop="handleApply(row)"
          >
            申请
          </el-button>
          <el-button class="text-primary" link @click.stop="handleUpdate(row)">
            编辑
          </el-button>
          <el-dropdown trigger="click">
            <el-button class="text-primary" link @click.stop> 更多 </el-button>
            <template #dropdown>
              <el-dropdown-menu class="w-20">
                <el-dropdown-item>
                  <el-button
                    type="primary"
                    link
                    @click.stop="handleDownload(row)"
                  >
                    下载
                  </el-button>
                </el-dropdown-item>
                <el-dropdown-item>
                  <el-button type="danger" link @click.stop="handleDelete(row)">
                    删除
                  </el-button>
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </div>
      </template>
    </el-table-column>
  </el-table>

  <cert-detail
    v-model:visible="detailState.visible"
    :record="detailState.record!"
    @refresh="emit('refresh')"
    @refresh-row="row => emit('refresh-row', row)"
  />
  <!-- 申请证书 -->
  <apply-cert-dialog
    v-model:visible="applyState.visible"
    v-model:loading="applyState.loading"
    :record="applyState.record"
    @refresh="emit('refresh')"
    @refresh-row="row => emit('refresh-row', row)"
  />
  <!-- 自签证书编辑 -->
  <edit-cert-dialog
    v-model:visible="editState.visible"
    v-model:loading="editState.loading"
    :record="editState.record"
    @refresh="emit('refresh')"
  />
  <edit-cert-drawer
    v-model:visible="editApplyState.visible"
    v-model:loading="editApplyState.loading"
    :record="editApplyState.record"
    @refresh="emit('refresh')"
    @refresh-row="row => emit('refresh-row', row)"
  />
  <!-- 日志 -->
  <log-dialog
    v-model:visible="logState.visible"
    :record="logState.record"
    @refresh-row="row => emit('refresh-row', row)"
  />
</template>

<script setup lang="ts">
// import { default as vElTableInfiniteScroll } from 'el-table-infinite-scroll'
import { type TableInstance } from 'element-plus'

import type { CertModel } from '@/apis/model/cert'
import {
  APPLY_METHOD,
  applyMethodOptions,
  CERT_COLOR_MAP,
  CERT_STATUS,
  certStatusOptions
} from '@/config/constant/cert'

import ApplyCertDialog from '../dialogs/ApplyCertDialog.vue'
import EditCertDialog from '../dialogs/EditCertDialog.vue'
import LogDialog from '../dialogs/LogDialog.vue'
import { normalLog } from '../state'
import EditCertDrawer from './ApplyCert.vue'
import CertDetail from './CertDetail/CertDetail.vue'
interface CertListModel extends CertModel {
  loading: boolean
}
type Pagination = {
  page: number
  limit: number
  offset: number
  total: number
}

interface IProps {
  checkAll: boolean
  loading: boolean
  disabled: boolean
  data: CertModel[]
  pagination: Partial<Pagination> & Record<string, any>
}
interface IEmits {
  (event: 'refresh', isDelete?: boolean): void
  (event: 'load-more'): void
  (event: 'sort-change', value: { sort: Sort; order: Order }): void
  (event: 'refresh-row', row: CertModel): void
}

const props = defineProps<IProps>()
const emit = defineEmits<IEmits>()
const tableRef = ref<TableInstance>()
const detailState = reactive({
  visible: false,
  record: undefined,
  loading: false
})
const applyState = reactive({
  visible: false,
  record: { id: '' },
  loading: false
})
const editState = reactive({
  visible: false,
  record: { id: '' },
  loading: false
})
const editApplyState = reactive({
  visible: false,
  record: { id: '' },
  loading: false
})
const logState = reactive({
  visible: false,
  record: undefined
})
const tableRowClassName = ({ row }: { row: CertModel }) => {
  if (selectedIds.value.includes(row.id!)) {
    return 'active-row'
  }
  return ''
}
//点击目标行 高亮，并清除其他行的选中样式
function handleTableRowClick(row: any) {
  if (!selectedIds.value.includes(row.id)) {
    nextTick(() => {
      tableRef.value?.toggleRowSelection(row, true)
    })
  } else {
    tableRef.value?.toggleRowSelection(row, false)
  }
}
const handleLog = (row: CertModel) => {
  normalLog(row.id!).then(() => {
    logState.record = { id: row.id, title: row.primary_domain } as any
    logState.visible = true
  })
}
const { toggleAll, getRows } = useTableUtils(tableRef, () => props.data)

const { setMessageBox } = useMessageBox()
// 表格批量操作
const { selectedIds, reset, handleTableSelectionChange } = useTableBatchAction(
  tableRef,
  props.data
)
function clearSelectIds() {
  nextTick(() => {
    tableRef.value?.clearSelection()
    reset()
  })
}
function handleSortChange(params: SortParams) {
  const { sort, order } = getSortValue(params)
  emit('sort-change', { sort, order })
}

function handleDetail(row: CertModel) {
  detailState.visible = true
  detailState.record = row as any
}
function handleApply(row: CertModel) {
  if (row.provider === 'self_signed') {
    setMessageBox({
      isHtml: true,
      icon: true,
      content: `<p>是否确定给域名 ${row.primary_domain} 申请证书？</p>`,
      title: '申请证书',
      async submit() {
        try {
          await renewSelfCaApi({ id: row.id } as any)
          ToastUtils.success('操作成功')
          emit('refresh')
          setMessageBox({ visible: false })
        } finally {
          setMessageBox({ loading: false })
        }
      }
    })
  } else {
    if (row.provider === APPLY_METHOD.HAND_ANALYSIS) {
      applyState.visible = true
      applyState.record = { ...row } as any
    } else {
      setMessageBox({
        isHtml: true,
        icon: true,
        content: `<p>是否确定给域名 ${row.primary_domain} 申请证书？</p>`,
        title: '申请证书',
        async submit() {
          try {
            await applyCertApi({ id: row.id } as any)
            logState.visible = true
            logState.record = { id: row.id, title: row.primary_domain } as any
            getCertApi({ id: row?.id! }).then(res => {
              emit('refresh-row', res)
            })
            setMessageBox({ visible: false })
          } finally {
            setMessageBox({ loading: false })
          }
        }
      })
    }
  }
}
function handleUpdate(row: CertModel) {
  if (row.provider === 'self_signed') {
    editState.visible = true
    editState.record = { ...editState.record, ...row }
  } else {
    editApplyState.visible = true
    editApplyState.record = { ...row } as any
  }
}
function handleDownload(row: CertModel) {
  downloadCertApi({ id_list: [row.id!] }).then((res: any) => {
    useDownloadZipByBase64(res.content, res.name)
  })
}
function handleDelete(row: CertModel) {
  setMessageBox({
    isHtml: true,
    content: '<p>确定删除此域名？</p>',
    title: '提示',
    async submit() {
      try {
        await deleteCertApi({ id_list: [row.id!] })
        ToastUtils.success('删除成功')
        emit('refresh', true)
        setMessageBox({ visible: false })
      } finally {
        setMessageBox({ loading: false })
      }
    }
  })
}
const handleChangeStatus = (row: CertListModel) => {
  row.loading = true
  return new Promise((resolve, reject) => {
    updateStatusApi({ id: row.id, auto_renew: !row.auto_renew } as any)
      .then(() => {
        return resolve(true)
      })
      .finally(() => (row.loading = false))
      .catch(err => reject(err))
  })
}
async function handleEditRemark(id: string, description: string) {
  await updateDescApi({
    id,
    description
  } as any)
  emit('refresh')
  ToastUtils.success('修改成功')
}

function setSelectIds(ids: string[]) {
  selectedIds.value = ids
  props.data.forEach((item: CertModel) => {
    if (selectedIds.value.includes(item.id!)) {
      nextTick(() => {
        tableRef?.value?.toggleRowSelection(item, true)
      })
    }
  })
}
defineExpose({
  getRows,
  toggleAll,
  selectedIds,
  reset: clearSelectIds,
  setSelectIds
})
</script>

<style lang="scss" scoped>
.basic-table {
  :deep(.el-table__header-wrapper) {
    .el-checkbox {
      padding: 8px;
    }
  }
  :deep(.el-table__row) {
    .el-checkbox {
      padding: 8px;
    }
  }
}
</style>
